/*
* 改造缓存存储
* 可以通过key.key.key的方式直接读取或者直接存入（仅支持对象）
* */
import CustomError from "./Error";
import Wx from "./Wx";
import {errorType} from "../main.config";

//异步存储
async function set(name, data) {
    try {
        let res = _setStorage(name, data);
        await Wx.setStorage(res.key, res.value);
        return res
    } catch (e) {
        throw new CustomError({
            actionName: "Storage.set",
            error: e,
            name: errorType.storage
        }).parse()
    }

}

//同步存缓存
function setSync(name, data) {
    try {
        let res = _setStorage(name, data);
        wx.setStorageSync(res.key, res.value);
        return res
    } catch (e) {
        throw new CustomError({
            actionName: "Storage.setSync",
            error: e,
            name: errorType.storage
        }).parse()
    }

}

//同步存缓存 -- 获取后即销毁
function getSyncOnce(name) {
    try {
        let res = _getStorage(name);
        _getStorageOnce(res);
        return res.value
    } catch (e) {
        throw new CustomError({
            actionName: "Storage.getSyncOnce",
            error: e,
            name: errorType.storage
        }).parse()
    }
}

//同步取缓存
function getSync(name) {  //同步存
    try {
        let res = _getStorage(name);
        return res.value
    } catch (e) {
        throw new CustomError({
            actionName: "Storage.getSync",
            error: e,
            name: errorType.storage
        }).parse()
    }
}

//异步清除
//为了不影响前台直接使用  捕获日志行为在内部进行
async function remove(name) {
    try {
        let res = _removeStorage(name);
        let {key, keys, value} = res
        if (keys.length === 1) {
            await Wx.removeStorage(key)
        } else {
            await Wx.setStorage(key, value);
        }
    } catch (e) {
        let error = new CustomError({
            actionName: "Storage.remove",
            error: e,
            name: errorType.storage
        }).parse();
        Wx.getLogManager("warn", error);
    }

}

//同步清除
function removeSync(name) {
    try {
        let res = _removeStorage(name);
        let {key, keys, value} = res;
        if (keys.length === 1) {
            wx.removeStorageSync(key);
        } else {
            wx.setStorageSync(key, value);
        }
        return res
    } catch (e) {
        throw new CustomError({
            actionName: "removeSync",
            error: e,
            name: errorType.storage
        }).parse()
    }
}

/*
* 解析参数
* 设置缓存信息
* */
function _setStorage(name, data) {
    let keys = name.split(".") || [];
    let storageKeyName = keys[0];
    let childKeys = null;
    let currentValue = null;
    let storage = null;
    if (!storageKeyName) {throw new CustomError("setStorage.key is not found");}
    if (keys.length === 1) {
        currentValue = data;
    } else {
        storage = wx.getStorageSync(storageKeyName) || {};
        let valueArr = [];
        for (let i = 0; i < keys.length; i ++) {
            if (i === 0) {
                valueArr.push(storage);
            } else if (i !== keys.length - 1) { //不是最后一个
                valueArr.push(storage[keys[i]] || {});
                storage = storage[keys[i]] || {};
            } else {
                valueArr.push(data || "");
            }
        }
        childKeys = keys.slice(1, keys.length);
        childKeys.reverse(); //倒序
        valueArr.reverse(); //倒序
        for (let p = 0; p < childKeys.length; p ++) {
            valueArr[p + 1][childKeys[p]] = valueArr[p]
        }
        currentValue = valueArr[valueArr.length - 1]
    }
    return {
        key: storageKeyName,
        value: currentValue
    };
}

/*
* 解析参数
* 获取缓存信息
* */
function _getStorage(name) {
    let keys = name.split(".") || [];
    let storageKeyName = keys[0];
    let currentValue = null;
    let valueArr = [];
    if (!storageKeyName) {throw new CustomError("getStorage.key is not found")}
    let storage = wx.getStorageSync(storageKeyName) || "";
    if (keys.length === 1) {
        currentValue = storage
    } else {
        for (let i = 0; i < keys.length; i ++) {
            if (i === 0) {
                valueArr.push(storage);
            } else {
                if (!storage) {
                    currentValue = storage;
                    break
                } else {
                    valueArr.push(storage[keys[i]]);
                    storage = storage[keys[i]];
                    currentValue = storage;
                }
            }
        }
    }
    return {
        keys: keys,
        key: storageKeyName,
        value: currentValue,
        valueArr: valueArr
    }
}

/*
* 获取缓存信息
* 缓存仅可使用一次 即刻作废
* 为了不影响前台直接使用  捕获日志行为在内部进行
* */
async function _getStorageOnce (res) {
    try {
        let {keys, key, valueArr} = res;
        let childKeys = null;
        if (keys.length === 1) {
            await Wx.removeStorage(key)
        } else if (valueArr.length === keys.length) { //最后字段值存在
            childKeys = keys.slice(1, keys.length);
            childKeys.reverse(); //倒序
            valueArr.reverse(); //倒序
            for (let p = 0; p < childKeys.length; p ++) {
                if (p === 0) {
                    delete valueArr[p + 1][childKeys[p]]
                } else {
                    valueArr[p + 1][childKeys[p]] = valueArr[p]
                }
            }
            await Wx.setStorage(key, valueArr[valueArr.length - 1]);
        }
        return res
    } catch (e) {
        let error = new CustomError(e).parse();
        Wx.getLogManager("warn", error);
    }
}

/*
* 解析参数
* 删除缓存信息
* */

function _removeStorage(name) {
    let keys = name.split(".") || [];
    let storageKeyName = keys[0];
    let storage = null;
    let childKeys = null;
    let valueArr = [];
    if (!storageKeyName) {throw new CustomError("removeStorage.key is not found");}
    if (keys.length > 1) {
        storage = wx.getStorageSync(storageKeyName) || {};
        for (let i = 0; i < keys.length; i ++) {
            if (i === 0) {
                valueArr.push(storage);
            } else {
                if (!storage) {
                    break
                } else {
                    valueArr.push(storage[keys[i]]);
                    storage = storage[keys[i]];
                }
            }
        }
        if (valueArr.length === keys.length) { //最后字段值存在
            childKeys = keys.slice(1, keys.length);
            childKeys.reverse(); //倒序
            valueArr.reverse(); //倒序
            for (let p = 0; p < childKeys.length; p ++) {
                if (p === 0) {
                    delete valueArr[p + 1][childKeys[p]]
                } else {
                    valueArr[p + 1][childKeys[p]] = valueArr[p]
                }
            }
        }
    }
    return {
        key: storageKeyName,
        keys: keys,
        value: valueArr[valueArr.length - 1]
    }
}

module.exports = {
    setStorage: set,
    setStorageSync: setSync,
    getStorageSyncOnce: getSyncOnce,
    getStorageSync: getSync,
    removeStorage: remove,
    removeStorageSync: removeSync
}